package PrzestrzenDyskretna;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import Zbiory.Element;
import Zbiory.Zbior;

import Narzedzia.ListaElementow;

public class DyskretnyZbiorRozmyty implements Zbior {

	private PrzestrzenDyskretna przestrzen;
	private ListaElementow<Element> elementy;

	public DyskretnyZbiorRozmyty(PrzestrzenDyskretna przestrzen, ListaElementow<Element> elementy) {
		super();
		this.przestrzen = przestrzen;
		this.elementy = elementy;
		Collections.sort(getElementy());
	}

	public DyskretnyZbiorRozmyty(PrzestrzenDyskretna przestrzen) {
		super();
		this.przestrzen = przestrzen;
		this.elementy = new ListaElementow<Element>();
	}

	public PrzestrzenDyskretna getPrzestrzen() {
		return przestrzen;
	}

	public boolean dodajElement(Element element) {
		boolean powodzenie = elementy.add(element);
		Collections.sort(getElementy());
		return powodzenie;
	}

	protected ListaElementow<Element> getElementy() {
		return elementy;
	}

	protected ListaElementow<Element> getNoweElementy() {
		ListaElementow<Element> lista = new ListaElementow<Element>();
		for (Element element : getElementy()) {
			lista.add(new Element(element));
		}
		return lista;
	}
	
	public boolean czyZawieraElement(Element element){
		if(elementy.contains(element)){
			return true;
		}
		return false;
	}

	public boolean czyNormalny() {

		Iterator<Element> iterator = getElementy().iterator();
		while (iterator.hasNext()) {
			Element element = (Element) iterator.next();
			if (getPrzynaleznosc(element) >= 1.0f) {
				return true;
			}
		}
		return false;
	}

	public boolean czyPusty() {
		if (getElementy().size() == 0)
			return true;
		return false;
	}

	public boolean czyWypukly() {
		for (float alfa = 0.0f; alfa < 1.0f; alfa += 0.01) {
			DyskretnyZbiorRozmyty alfaPrzekroj = new AlfaPrzekrojDyskretnyZbiorRozmyty(this, alfa);
			if (czyZbiorWypukly(alfaPrzekroj) == false) {
				return false;
			}
		}
		return true;
	}

	private boolean czyZbiorWypukly(DyskretnyZbiorRozmyty zbior) {
		Element start = zbior.poczatekNiezerowychPrzynaleznosci();
		Element stop = zbior.koniecNiezerowychPrzynaleznosci();
		boolean sprawdzaj = false;
		for (Element element : zbior.getElementy()) {
			if (element.compareTo(stop) == 0) {
				break;
			}
			if (element.compareTo(start) == 0) {
				sprawdzaj = true;
			}
			if (sprawdzaj && zbior.getPrzynaleznosc(element) < 1.0f) {
				return false;
			}
		}
		return true;
	}

	public boolean czyWklesly() {
		return !czyWypukly();
	}
	
	public int getRozmiar(){
		return elementy.size();
	}

	public float getWysokosc() {

		float wysokosc = 0.0f;
		Iterator<Element> iterator = getElementy().iterator();
		while (iterator.hasNext()) {
			Element element = iterator.next();
			if (getPrzynaleznosc(element) >= wysokosc) {
				wysokosc = getPrzynaleznosc(element);
			}
		}

		return wysokosc;
	}

	public float getPrzynaleznosc(Element element) {
		if (!getElementy().contains(element)) {
			return 0.0f;
		}

		Iterator<Element> iterator = getElementy().iterator();
		while (iterator.hasNext()) {
			Element elem = iterator.next();
			if (elem.compareTo(element) == 0) {
				return elem.getPrzynaleznosc();
			}
		}
		throw new IllegalStateException("Funkcja DyskretnyZbiorRozmyty.getPrzynaleznosc napotkala blad wykonania."
				+ " Funkcja getElementy().contains(element) zwrocila true, ale po przeiterowaniu po wszystkich elementach nie znaleziono elementu w liscie.");
	}

	public Element poczatekNiezerowychPrzynaleznosci() {
		for (Element element : getElementy()) {
			if (getPrzynaleznosc(element) > 0.0f) {
				return element;
			}
		}
		throw new IllegalStateException("Zbior jest pusty!");
	}

	public Element koniecNiezerowychPrzynaleznosci() {
		Element ostatniNiezerowyElement = null;
		for (Element element : getElementy()) {
			if (getPrzynaleznosc(element) > 0.0f) {
				ostatniNiezerowyElement = element;
			}
		}
		if (ostatniNiezerowyElement != null) {
			return ostatniNiezerowyElement;
		}
		throw new IllegalStateException("Zbior jest pusty!");
	}


	protected static PrzestrzenDyskretna nowaPrzestrzen(List<DyskretnyZbiorRozmyty> listaZbiorow) {
		ListaElementow<Element> elementy = new ListaElementow<Element>();
		for (DyskretnyZbiorRozmyty dyskretnyZbiorRozmyty : listaZbiorow) {
			for (Element element : dyskretnyZbiorRozmyty.getPrzestrzen().getElementy()) {
				elementy.add(element);
			}
		}
		return new PrzestrzenDyskretna(elementy);
	}

	protected static List<DyskretnyZbiorRozmyty> nowaListaZbiorow(DyskretnyZbiorRozmyty zbior1, DyskretnyZbiorRozmyty zbior2) {

		List<DyskretnyZbiorRozmyty> listaZbiorow = new ArrayList<DyskretnyZbiorRozmyty>(2);
		listaZbiorow.add(zbior1);
		listaZbiorow.add(zbior2);
		return listaZbiorow;
	}
}
